//Linkwish's code
#include<bits/stdc++.h>
#define endl '\n'
#define si inline
#define fi first
#define se second
using namespace std;
typedef long long ll;typedef __int128 li;typedef long double ld;
typedef pair<int,int> pii;typedef pair<ll,ll> pll;typedef unsigned long long ull;
typedef const int ci;typedef const ll cl;ci iinf=INT_MAX;cl linf=LLONG_MAX;
template<typename T>si bool gmax(T &x,const T y){if(x<y)return x=y,1;return 0;}
template<typename T>si bool gmin(T &x,const T y){if(y<x)return x=y,1;return 0;}

namespace LinkWish{

	ci N=400005,T=500;

	struct Dynamic_Bitset{
		ci Bit=6,Block=(1<<Bit),sig=Block-1;
		
		vector<ull> v;

		si void resize(int x){
			v.resize((x+Block-1)/Block);
			for(ull &i:v)i=0;
		}

		si void Set(int x){
			v[x>>Bit]|=(1ull<<(x&sig));
		}

		si int ask(int x){
			return (v[x>>Bit]>>(x&sig))&1;
		}

		si int operator & (const Dynamic_Bitset &obj)const{
			int res=0;
			for(int i=0;i<(int)v.size();i++)res+=__builtin_popcountll(v[i]&obj.v[i]);
			return res;
		}

		si void operator |= (const Dynamic_Bitset &obj){
			for(int i=0;i<(int)v.size();i++)v[i]|=obj.v[i];
		}
	};

	int n,m,K,lb,rb;
	int a[N];
	vector<int> e[N];

	int cnt;
	vector<pii> g[N];

	Dynamic_Bitset A[1<<7],B[1<<8];

	si void add(int x,int y){g[x].emplace_back(y,0),g[y].emplace_back(x,0);}
	void build(int x,int fa){
		if(fa!=0)e[x].erase(find(e[x].begin(),e[x].end(),fa));
		for(int to:e[x])build(to,x);
		int now=x,las=-1,rp=-1;
		if(!e[x].empty())rp=e[x].back(),e[x].pop_back();
		for(int to:e[x]){
			if(~las)now=++cnt,a[now]=a[x],add(las,now);
			add(now,to),las=now;
		}
		if(~rp)add(now,rp);
	}

	int ans[N];
	vector<pii> que[N];

	int sz[N],ssz[N];
	void getsz(int x,int fa){
		ssz[x]=1;
		for(pii i:g[x])if(!i.se&&i.fi!=fa)getsz(i.fi,x),ssz[x]+=ssz[i.fi];
	}
	void getrt(int x,int fa,int &rt1,int &rt2,ci S){
		for(pii i:g[x]){
			if(i.fi!=fa&&!i.se){
				int to=i.fi;getrt(to,x,rt1,rt2,S);
				if(rt1==-1||abs(S-ssz[to]-ssz[to])<abs(S-ssz[rt2]-ssz[rt2]))rt1=x,rt2=to;
			}
		}
	}

	int val[N],dfn[N],sign;
	void getpnt(int x,int fa,vector<int> &pnt){
		val[x]|=(1<<a[x]);
		if(x<=n)sz[x]=1,dfn[x]=sign++,pnt.push_back(x);
		else sz[x]=0;
		for(pii i:g[x])if(i.fi!=fa&&!i.se)val[i.fi]=val[x],getpnt(i.fi,x,pnt),sz[x]+=sz[i.fi];
	}

	int vis[1<<15];
	vector<int> dl;
	si void Clear(int S){
		for(int i:dl)vis[i]=-1;
		dl.clear();
		for(int i=0;i<(1<<lb);i++)A[i].resize(S);
		for(int i=0;i<(1<<rb);i++)B[i].resize(S);
	}
	si void ins(int x){
		A[val[x]&((1<<lb)-1)].Set(dfn[x]);
		B[val[x]>>lb].Set(dfn[x]);
	}
	si int ask(int S){
		if(vis[S]!=-1)return vis[S];
		vis[S]=A[S&((1<<lb)-1)]&B[S>>lb];
		dl.push_back(S);
		return vis[S];
	}

	void solve(int x){
		getsz(x,0);
		int nrt=x,y=-1;x=-1;
		getrt(nrt,0,x,y,ssz[nrt]);
		if(x==-1)return ;

		vector<int> xp,yp;
		val[x]=val[y]=0;
		sign=0,getpnt(x,y,xp);
		sign=0,getpnt(y,x,yp);

		if(sz[y]!=0){
			if(sz[y]>T){
				Clear(sz[y]);
				for(int i:yp)ins(i);
				for(int i=0;i<lb;i++)
					for(int j=0;j<(1<<lb);j++)
						if(!(j&(1<<i)))A[j|(1<<i)]|=A[j];
				for(int i=0;i<rb;i++)
					for(int j=0;j<(1<<rb);j++)
						if(!(j&(1<<i)))B[j|(1<<i)]|=B[j];
				for(int i:xp){
					for(pii j:que[i]){
						int S=j.fi,id=j.se;
						if((S&val[i])==val[i])ans[id]+=ask(S);
					}
				}
			}
			else{
				for(int i:xp){
					for(pii j:que[i]){
						int S=j.fi,id=j.se;
						if((S&val[i])==val[i])
							for(int k:yp)if((S&val[k])==val[k])ans[id]++;
					}
				}
			}
		}
		if(sz[x]!=0){
			if(sz[x]>T){
				Clear(sz[x]);
				for(int i:xp)ins(i);
				for(int i=0;i<lb;i++)
					for(int j=0;j<(1<<lb);j++)
						if(!(j&(1<<i)))A[j|(1<<i)]|=A[j];
				for(int i=0;i<rb;i++)
					for(int j=0;j<(1<<rb);j++)
						if(!(j&(1<<i)))B[j|(1<<i)]|=B[j];

				for(int i:yp){
					for(pii j:que[i]){
						int S=j.fi,id=j.se;
						if((S&val[i])==val[i])ans[id]+=ask(S);
					}
				}
			}
			else{
				for(int i:yp){
					for(pii j:que[i]){
						int S=j.fi,id=j.se;
						if((S&val[i])==val[i])
							for(int k:xp)if((S&val[k])==val[k])ans[id]++;
					}
				}
			}
		}

		for(pii &i:g[x])if(i.fi==y)i.se=1;
		for(pii &i:g[y])if(i.fi==x)i.se=1;

		bool flagx=(sz[x]!=0),flagy=(sz[y]!=0);
		if(flagx)solve(x);
		if(flagy)solve(y);
	}

	void mian(){
		cin>>n>>m>>K,lb=K/2,rb=K-lb;
		for(int i=1;i<=n;i++)cin>>a[i];
		for(int i=2,x;i<=n;i++)cin>>x,e[x].push_back(i),e[i].push_back(x);

		for(int i=1,x,y;i<=m;i++)cin>>x>>y,que[y].emplace_back(x,i),ans[i]=1;
		
		cnt=n,build(1,0);

		memset(vis,-1,sizeof vis);
		solve(1);

		for(int i=1;i<=m;i++)cout<<ans[i]<<endl;
	}
}

signed main(){
	freopen("tree.in","r",stdin);
	freopen("tree.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	LinkWish::mian();
	return 0;
}